/*
 * XMLOutputMesoscopicInterface.cpp
 *
 *  Created on: 17/10/2011
 *      Author: godinho
 */

#include "XMLOutputMesoscopicInterface.h"
#include "Network.h"
#include "SimulationNode.h"
#include "TLSPhase.h"
#include "NodeInput.h"
#include "NodeSource.h"
#include "TLSLink.h"

#include <vector>


XMLOutputMesoscopicInterface::XMLOutputMesoscopicInterface(std::string fileName) : mFileName(fileName) {
}

XMLOutputMesoscopicInterface::~XMLOutputMesoscopicInterface() {

}

void XMLOutputMesoscopicInterface::startStep(int step, Network* network) {
	mFileStream << "<step id='" << step << "'>\n";
}

void XMLOutputMesoscopicInterface::endStep(int step, Network* network) {

	std::vector<SimulationNode*> nodes = network->getNodes();
	std::map<SimulationNode*, NodeInput*> nodeInputs;
	std::map<SimulationNode*, NodeInput*>::iterator nodeInputsIt;
	std::vector<int> flush;
	std::vector<int> queue;

	for(std::vector<SimulationNode*>::iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); nodeIt++) {
		nodeInputs = (*nodeIt)->getNodeInputMap();
		flush.clear();
		queue.clear();

		mFileStream << "\t<node id='" << (*nodeIt)->getId() << "'>\n";

		for(nodeInputsIt = nodeInputs.begin(); nodeInputsIt != nodeInputs.end(); nodeInputsIt++) {
			flush.push_back((*nodeInputsIt).second->getFlush());
			queue.push_back((*nodeInputsIt).second->getQueueSize());
		}

		mFileStream << "\t\t<flush>";
		for(std::vector<int>::iterator it = flush.begin(); it != flush.end(); it++) {
			mFileStream << (*it) << " ";
		}
		mFileStream << "</flush>\n";

		mFileStream << "\t\t<queue>";
		for(std::vector<int>::iterator it = queue.begin(); it != queue.end(); it++) {
			mFileStream << (*it) << " ";
		}
		mFileStream << "</queue>\n";

		TLSPhase* currentPhase = (*nodeIt)->getCurrentPhase();

		if(currentPhase != 0) {
			mFileStream << "\t\t<phase id=\"" << currentPhase->getId() << "\"" <<
								  " time=\"" << currentPhase->getDuration() << "\"/>\n";
		}

		mFileStream << "\t</node>\n";
	}

	//Sources
	std::vector<NodeSource*> source = network->getSources();
	std::vector<NodeSource*>::iterator it;

	int i = 0;
	for(it = source.begin(); it != source.end(); it++){
		mFileStream << "\t<carsource index=\"" << i << "\" amount=\"" << (*it)->getLastGeneratedAmount() << "\"/>\n" ;
		i++;
	}

	mFileStream << "</step>\n";
}

void XMLOutputMesoscopicInterface::startSimulation(Network* network) {
	mFileStream.open(mFileName.c_str());

	mFileStream << "<mesoscopic>\n";
	dumpNetwork(network);
}

void XMLOutputMesoscopicInterface::dumpNetwork(Network* network) {

	std::vector<SimulationNode*> nodes = network->getNodes();
	std::vector<SimulationNode*>::iterator nodesIt;

	mFileStream << "<network>\n";

	//Write nodes
	for(nodesIt = nodes.begin(); nodesIt != nodes.end(); nodesIt++) {
		mFileStream << "\t<node id=\"" << (*nodesIt)->getId() << "\"" <<
								" x=\"" << (*nodesIt)->getX() << "\"" <<
								" y=\"" << (*nodesIt)->getY() << "\"" <<
					">\n";

		std::vector<TLSPhase*> phases = (*nodesIt)->getPhases();
		std::vector<TLSPhase*>::iterator phasesIt;

		for(phasesIt = phases.begin(); phasesIt != phases.end(); phasesIt++) {
			mFileStream << "\t\t<phase id=\"" << (*phasesIt)->getId() << "\">\n";

			std::vector<TLSLink*> links = (*phasesIt)->getLinks();
			std::vector<TLSLink*>::iterator linksIt;

			for(linksIt = links.begin(); linksIt != links.end(); linksIt++) {
				mFileStream << "\t\t\t<link from=\"" << (*linksIt)->getFrom()->getId() << "\"" <<
										    " to=\"" << (*linksIt)->getTo()->getId() << "\"/>\n";
			}

			mFileStream << "\t\t</phase>\n";
		}

		mFileStream << "\t</node>\n";
	}

	for(nodesIt = nodes.begin(); nodesIt != nodes.end(); nodesIt++) {
		std::vector<SimulationNode*> outNodes = (*nodesIt)->getOutcomingNodes();
		std::vector<SimulationNode*>::iterator outNodesIt;

		//Write edges
		for(outNodesIt = outNodes.begin(); outNodesIt != outNodes.end(); outNodesIt++) {
					mFileStream << "\t<edge from=\"" << (*nodesIt)->getId() << "\"" <<
											" to=\"" << (*outNodesIt)->getId() << "\""
											"/>\n";
		}
	}

	std::vector<NodeSource*> sources = network->getSources();
	std::vector<NodeSource*>::iterator it;

	for(it = sources.begin(); it != sources.end(); it++) {
		mFileStream << "\t<carsource node=\"" << (*it)->getNode()->getId() << "\""
				<< " target=\"" << (*it)->getTarget()->getId() << "\""
				<< " arrivalRate=\"" << (*it)->getArrivalRate() << "\"/>\n";
	}

	mFileStream << "</network>\n";
}

void XMLOutputMesoscopicInterface::endSimulation(Network* network) {
	mFileStream << "</mesoscopic>\n";
	mFileStream.close();
}

